using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Interop;
using log4net;
using Triton.Common.LogUtilities;

namespace Triton.Common
{
	public static class Hotkeys
	{
		[CompilerGenerated]
		private sealed class Class231
		{
			public string string_0;

			internal bool method_0(Hotkey hotkey_0)
			{
				return hotkey_0.Name == string_0;
			}
		}

		[CompilerGenerated]
		private sealed class Class232
		{
			public MSG msg_0;

			public Func<Hotkey, bool> func_0;

			internal bool method_0(Hotkey hotkey_0)
			{
				return hotkey_0.Id == (int)msg_0.wParam;
			}
		}

		private static readonly ILog ilog_0 = Logger.GetLoggerInstanceForType();

		private static readonly List<Hotkey> list_0 = new List<Hotkey>();

		private const int int_0 = 786;

		private static bool bool_0;

		private static IntPtr intptr_0;

		private static int int_1;

		private static object object_0 = new object();

		private static Thread thread_0;

		private static readonly Queue<Hotkey> queue_0 = new Queue<Hotkey>();

		private static readonly Queue<Hotkey> queue_1 = new Queue<Hotkey>();

		public static IEnumerable<Hotkey> RegisteredHotkeys => list_0.AsReadOnly();

		internal static bool Boolean_0 => GetForegroundWindow() == intptr_0;

		public static Hotkey Register(string name, Keys key, ModifierKeys modifierKeys, Action<Hotkey> callback)
		{
			Hotkey hotkey = new Hotkey(name, key, modifierKeys, int_1++, callback);
			lock (queue_0)
			{
				queue_0.Enqueue(hotkey);
			}
			list_0.Add(hotkey);
			smethod_2();
			return hotkey;
		}

		public static void Unregister(string name)
		{
			Unregister(list_0.FirstOrDefault((Hotkey hotkey_0) => hotkey_0.Name == name));
		}

		public static void Unregister(Hotkey hotkey)
		{
			if (hotkey != null)
			{
				lock (queue_1)
				{
					queue_1.Enqueue(hotkey);
				}
				list_0.Remove(hotkey);
			}
		}

		[DllImport("user32.dll")]
		internal static extern IntPtr GetForegroundWindow();

		[DllImport("user32.dll", SetLastError = true)]
		[return: MarshalAs(UnmanagedType.Bool)]
		private static extern bool RegisterHotKey(IntPtr intptr_1, int int_2, uint uint_0, uint uint_1);

		[DllImport("user32.dll")]
		private static extern bool UnregisterHotKey(IntPtr intptr_1, int int_2);

		[DllImport("user32.dll")]
		[return: MarshalAs(UnmanagedType.Bool)]
		private static extern bool PeekMessage(out MSG msg_0, IntPtr intptr_1, uint uint_0, uint uint_1, uint uint_2);

		public static void Initialize(IntPtr windowHandleToWatch)
		{
			if (!bool_0)
			{
				MouseHook.smethod_0();
				intptr_0 = windowHandleToWatch;
				bool_0 = true;
			}
		}

		private static void smethod_0(Hotkey hotkey_0)
		{
			if (!hotkey_0.Boolean_0 && RegisterHotKey(IntPtr.Zero, hotkey_0.Id, (uint)hotkey_0.ModifierKeys, (uint)hotkey_0.Key))
			{
				hotkey_0.Boolean_0 = true;
			}
		}

		private static void smethod_1(Hotkey hotkey_0)
		{
			if (hotkey_0.Boolean_0 && UnregisterHotKey(IntPtr.Zero, hotkey_0.Id))
			{
				hotkey_0.Boolean_0 = false;
			}
		}

		private static void smethod_2()
		{
			lock (object_0)
			{
				if (thread_0 == null)
				{
					thread_0 = new Thread(smethod_3)
					{
						Name = "Hotkey Processing Loop",
						IsBackground = true
					};
					thread_0.Start();
				}
			}
		}

		private static void smethod_3()
		{
			while (true)
			{
				Queue<Hotkey> queue = new Queue<Hotkey>();
				Queue<Hotkey> queue2 = new Queue<Hotkey>();
				lock (queue_0)
				{
					while (queue_0.Count != 0)
					{
						queue.Enqueue(queue_0.Dequeue());
					}
				}
				lock (queue_1)
				{
					while (queue_1.Count != 0)
					{
						queue2.Enqueue(queue_1.Dequeue());
					}
				}
				while (queue.Count != 0)
				{
					smethod_0(queue.Dequeue());
				}
				while (queue2.Count != 0)
				{
					smethod_1(queue2.Dequeue());
				}
				if (!Boolean_0)
				{
					foreach (Hotkey item in list_0)
					{
						smethod_1(item);
					}
				}
				else
				{
					foreach (Hotkey item2 in list_0)
					{
						smethod_0(item2);
					}
					MouseHook.smethod_0();
					smethod_4();
				}
				Thread.Sleep(100);
			}
		}

		private static void smethod_4()
		{
			MSG msg_0;
			while (PeekMessage(out msg_0, IntPtr.Zero, 786u, 786u, 1u))
			{
				Hotkey hotkey = RegisteredHotkeys.FirstOrDefault((Hotkey hotkey_0) => hotkey_0.Id == (int)msg_0.wParam);
				if (hotkey != null)
				{
					ilog_0.DebugFormat(hotkey.Name + " pressed.");
					hotkey.Callback(hotkey);
				}
			}
		}
	}
}
